home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / cv_coord.pro < prev    next >
Text File  |  1997-07-08  |  10KB  |  262 lines

  1. ; $Id: cv_coord.pro,v 1.3 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1994-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;       CV_COORD
  8. ;
  9. ; PURPOSE:
  10. ;       Converts 2-D and 3-D coordinates between the RECTANGULAR, POLAR,
  11. ;       CYLINDRICAL, and SPHERICAL coordinate systems.
  12. ;
  13. ; CATEGORY:
  14. ;       Graphics
  15. ;
  16. ; CALLING SEQUENCE:
  17. ;       Coord = CV_COORD()
  18. ;
  19. ; KEYWORD PARAMETERS:
  20. ;
  21. ;       FROM_RECT:
  22. ;                  A vector of the form [x, y] or [x, y, z], or a (2, n) or
  23. ;                  (3, n) array containing rectangular coordinates to convert.
  24. ;
  25. ;       FROM_POLAR:
  26. ;                  A vector of the form [angle, radius], or a (2, n) array of
  27. ;                  polar coordinates to convert.
  28. ;
  29. ;       FROM_CYLIN:
  30. ;                  A vector of the form [angle, radius, z], or a (3, n) array
  31. ;                  of cylindrical coordinates to convert.
  32. ;
  33. ;       FROM_SPHERE:
  34. ;                  A vector of the form [longitude, latitude, radius], or a
  35. ;                  (3, n) array of spherical coordinates to convert.
  36. ;
  37. ;       TO_RECT:   If set, then rectangular coordinates are returned.
  38. ;
  39. ;       TO_POLAR:  If set, then polar coordinates are returned.
  40. ;
  41. ;       TO_CYLIN:  If set, then cylindrical coordinates are returned.
  42. ;
  43. ;       TO_SPHERE: If set, then spherical coordinates are returned.
  44. ;
  45. ;       DEGREES:   If set, then the input (and output) coordinates are in
  46. ;                  degrees (where applicable). Otherwise, the angles are
  47. ;                  in radians.
  48. ;
  49. ; OUTPUTS:
  50. ;       This function returns the converted coordinate(s) based on which of
  51. ;       the "TO_" keywords is used :
  52. ;
  53. ;          TO_RECT   : If the input coordinates were polar, then a vector
  54. ;                      of the form [x, y] or a (2, n) array is returned.
  55. ;                      Otherwise, a vector of the form [x, y, z], or a
  56. ;                      (3, n) array is returned.
  57. ;          TO_POLAR  : A vector of the form [angle, radius], or a (2, n)
  58. ;                      array is returned.
  59. ;          TO_CYLIN  : A vector of the form [angle, radius, z], or a (3, n)
  60. ;                      array is returned.
  61. ;          TO_SPHERE : A vector of the form [longitude, latitude, radius],
  62. ;                      or a (3, n) array is returned.
  63. ;
  64. ;       If the value passed to the "FROM_" keyword is double precision, then
  65. ;       all calculations are performed in double precision and the returned
  66. ;       value is double precision. Otherwise, single precision is used.
  67. ;
  68. ;       If none of the "FROM_" keywords are specified then 0 is returned.
  69. ;       If none of the "TO_" keywords are specified then the input coordinates
  70. ;       are returned.
  71. ;
  72. ; PROCEDURE:
  73. ;       When converting from spherical to polar coordinates, the points
  74. ;       are first projected along the z axis to the x-y plane to get 2-D
  75. ;       rectangular coordinates. The 2-D rectangular coordinates are
  76. ;       then converted to polar.
  77. ;
  78. ; EXAMPLE:
  79. ;       ; Convert from spherical to cylindrical coordinates.
  80. ;
  81. ;       sphere_coord = [[45.0, -60.0, 10.0], [0.0, 0.0, 0.0]]
  82. ;       rect_coord = CV_COORD(From_Sphere=sphere_coord, /To_Cylin, /Degrees)
  83. ;
  84. ;       ; Convert from rectangular to polar coordinates.
  85. ;
  86. ;       rect_coord = [10.0, 10.0]
  87. ;       polar_coord = CV_COORD(From_Rect=rect_coord, /To_Polar)
  88. ;
  89. ; MODIFICATION HISTORY:
  90. ;       Written by:     Daniel Carr, Thu Mar 31 14:42:58 MST 1994
  91. ;-
  92.  
  93. FUNCTION CV_COORD, From_Rect=from_rect, From_Polar=from_polar, $
  94.                    From_Cylin=from_cylin, From_Sphere=from_sphere, $
  95.                    To_Rect=to_rect, To_Polar=to_polar, $
  96.                    To_Cylin=to_cylin, To_Sphere=to_sphere, $
  97.                    Degrees=degrees
  98.  
  99. IF (N_Elements(from_rect) GT 0L) THEN BEGIN ; Convert from rectangular.
  100.    sz_from = Size(from_rect)
  101.    IF (sz_from[0] EQ 1L) THEN $
  102.       sz_from = [2L, sz_from[1], 1L, sz_from[2], sz_from[3]]
  103.  
  104.    IF (sz_from[sz_from[0] + 2L] EQ 5L) THEN BEGIN ; Double precision.
  105.       IF (Keyword_Set(degrees)) THEN ang_out = 180.0D/!DPI ELSE ang_out = 1.0D
  106.       zero = 0.0D
  107.    ENDIF ELSE BEGIN ; Single precision
  108.       IF (Keyword_Set(degrees)) THEN ang_out = !Radeg ELSE ang_out = 1.0
  109.       zero = 0.0
  110.    ENDELSE
  111.  
  112.    IF (Keyword_Set(to_polar)) THEN BEGIN
  113.       ang = Replicate(zero, 1L, sz_from[2])
  114.       rad = Sqrt(from_rect[0, *]^2 + from_rect[1, *]^2)
  115.       non_zero_ind = Where(rad NE zero)
  116.       IF (non_zero_ind[0] GE 0L) THEN $
  117.          ang[non_zero_ind] = ang_out * $
  118.             Atan(from_rect[1, non_zero_ind], from_rect[0, non_zero_ind])
  119.       RETURN, [ang, rad]
  120.    ENDIF
  121.  
  122.    IF (Keyword_Set(to_cylin)) THEN BEGIN
  123.       ang = Replicate(zero, 1L, sz_from[2])
  124.       rad = Sqrt(from_rect[0, *]^2 + from_rect[1, *]^2)
  125.       non_zero_ind = Where(rad NE zero)
  126.       IF (non_zero_ind[0] GE 0L) THEN $
  127.          ang[non_zero_ind] = ang_out * $
  128.             Atan(from_rect[1, non_zero_ind], from_rect[0, non_zero_ind])
  129.       IF (sz_from[1] GE 3L) THEN RETURN, [ang, rad, from_rect[2, *]] $
  130.       ELSE RETURN, [ang, rad, Replicate(zero, 1L, sz_from[2])]
  131.    ENDIF
  132.  
  133.    IF (Keyword_Set(to_sphere)) THEN BEGIN
  134.       ang1 = Replicate(zero, 1L, sz_from[2])
  135.       ang2 = Replicate(zero, 1L, sz_from[2])
  136.       IF (sz_from[1] LT 3L) THEN z = Replicate(zero, 1L, sz_from[2]) $
  137.       ELSE z = from_rect[2, *]
  138.       rad = Sqrt(from_rect[0, *]^2 + from_rect[1, *]^2 + z^2)
  139.       non_zero_ind = Where(rad GT zero)
  140.       IF (non_zero_ind[0] GE 0L) THEN BEGIN
  141.          ang1[non_zero_ind] = ang_out * $
  142.             Atan(from_rect[1, non_zero_ind], from_rect[0, non_zero_ind])
  143.          ang2[non_zero_ind] = ang_out * Atan(z[0, non_zero_ind], $
  144.             Sqrt(from_rect[0, non_zero_ind]^2 + from_rect[1, non_zero_ind]^2))
  145.       ENDIF
  146.       RETURN, [ang1, ang2, rad]
  147.    ENDIF
  148.  
  149.    RETURN, from_rect
  150. ENDIF
  151.  
  152. IF (N_Elements(from_polar) GT 0L) THEN BEGIN ; Convert from polar.
  153.    sz_from = Size(from_polar)
  154.    IF (sz_from[0] EQ 1L) THEN $
  155.       sz_from = [2L, sz_from[1], 1L, sz_from[2], sz_from[3]]
  156.  
  157.    IF (sz_from[sz_from[0] + 2L] EQ 5L) THEN BEGIN ; Double precision.
  158.       IF (Keyword_Set(degrees)) THEN ang_in = !DPI/180.0D ELSE ang_in = 1.0D
  159.       zero = 0.0D
  160.    ENDIF ELSE BEGIN ; Single precision
  161.       IF (Keyword_Set(degrees)) THEN ang_in = !Dtor ELSE ang_in = 1.0
  162.       zero = 0.0
  163.    ENDELSE
  164.  
  165.    IF (Keyword_Set(to_rect)) THEN $
  166.       RETURN, [from_polar[1, *] * Cos(ang_in * from_polar[0, *]), $
  167.                from_polar[1, *] * Sin(ang_in * from_polar[0, *])]
  168.  
  169.    IF (Keyword_Set(to_cylin)) THEN $
  170.       RETURN, [from_polar[0, *], from_polar[1, *], $
  171.                Replicate(zero, 1, sz_from[2])]
  172.  
  173.    IF (Keyword_Set(to_sphere)) THEN $
  174.       RETURN, [from_polar[0, *], Replicate(zero, 1, sz_from[2]), $
  175.                from_polar[1, *]]
  176.  
  177.    RETURN, from_polar
  178. ENDIF
  179.  
  180. IF (N_Elements(from_cylin) GT 0L) THEN BEGIN ; Convert from cylindrical.
  181.    sz_from = Size(from_cylin)
  182.    IF (sz_from[0] EQ 1L) THEN $
  183.       sz_from = [2L, sz_from[1], 1L, sz_from[2], sz_from[3]]
  184.  
  185.    IF (sz_from[sz_from[0] + 2L] EQ 5L) THEN BEGIN ; Double precision.
  186.       IF (Keyword_Set(degrees)) THEN BEGIN
  187.          ang_in = !DPI/180.0D
  188.          ang_out = 180.0D/!DPI
  189.       ENDIF ELSE BEGIN
  190.          ang_in = 1.0D
  191.          ang_out = 1.0D
  192.       ENDELSE
  193.       zero = 0.0D
  194.    ENDIF ELSE BEGIN ; Single precision
  195.       IF (Keyword_Set(degrees)) THEN BEGIN
  196.          ang_in = !Dtor
  197.          ang_out = !Radeg
  198.       ENDIF ELSE BEGIN
  199.          ang_in = 1.0
  200.          ang_out = 1.0
  201.       ENDELSE
  202.       zero = 0.0
  203.    ENDELSE
  204.  
  205.    IF (Keyword_Set(to_rect)) THEN $
  206.       RETURN, [from_cylin[1, *] * Cos(ang_in * from_cylin[0, *]), $
  207.                from_cylin[1, *] * Sin(ang_in * from_cylin[0, *]), $
  208.                from_cylin[2, *]]
  209.  
  210.    IF (Keyword_Set(to_polar)) THEN RETURN, [from_cylin[0, *], from_cylin[1, *]]
  211.  
  212.    IF (Keyword_Set(to_sphere)) THEN BEGIN
  213.       ang1 = from_cylin[0, *]
  214.       ang2 = Replicate(zero, 1L, sz_from[2])
  215.       rad = Sqrt(from_cylin[1, *]^2 + from_cylin[2, *]^2)
  216.       non_zero_ind = Where(rad GT zero)
  217.       IF (non_zero_ind[0] GE 0L) THEN $
  218.          ang2[non_zero_ind] = ang_out * Atan(from_cylin[2, non_zero_ind], $
  219.                                              from_cylin[1, non_zero_ind])
  220.       RETURN, [ang1, ang2, rad]
  221.    ENDIF
  222.  
  223.    RETURN, from_cylin
  224. ENDIF
  225.  
  226. IF (N_Elements(from_sphere) GT 0L) THEN BEGIN ; Convert from spherical.
  227.    sz_from = Size(from_sphere)
  228.    IF (sz_from[0] EQ 1L) THEN $
  229.       sz_from = [2L, sz_from[1], 1L, sz_from[2], sz_from[3]]
  230.  
  231.    IF (sz_from[sz_from[0] + 2L] EQ 5L) THEN BEGIN ; Double precision.
  232.       IF (Keyword_Set(degrees)) THEN ang_in = !DPI/180.0D ELSE ang_in = 1.0D
  233.       zero = 0.0D
  234.    ENDIF ELSE BEGIN ; Single precision
  235.       IF (Keyword_Set(degrees)) THEN ang_in = !Dtor ELSE ang_in = 1.0
  236.       zero = 0.0
  237.    ENDELSE
  238.  
  239.    IF (Keyword_Set(to_rect)) THEN BEGIN
  240.       RETURN, [ $
  241.           from_sphere[2, *] * Cos(ang_in * from_sphere[0, *]) * $
  242.                                      Cos(ang_in * from_sphere[1, *]), $
  243.           from_sphere[2, *] * Sin(ang_in * from_sphere[0, *]) * $
  244.                                      Cos(ang_in * from_sphere[1, *]), $
  245.           from_sphere[2, *] * Sin(ang_in * from_sphere[1, *])]
  246.    ENDIF
  247.  
  248.    IF (Keyword_Set(to_polar)) THEN $
  249.       RETURN, [from_sphere[0, *], $
  250.                from_sphere[2, *] * Cos(ang_in * from_sphere[1, *])]
  251.  
  252.    IF (Keyword_Set(to_cylin)) THEN $
  253.       RETURN, [from_sphere[0, *], $
  254.                from_sphere[2, *] * Cos(ang_in * from_sphere[1, *]), $
  255.                from_sphere[2, *] * Sin(ang_in * from_sphere[1, *])]
  256.  
  257.    RETURN, from_sphere
  258. ENDIF
  259.  
  260. RETURN, 0
  261. END
  262.